// $Id: file_stat.c 13 2011-08-11 08:26:12Z mygoddes@yeah.net $
/////////////////////////////////////////////////////////////////////////
// Purpose : learn to use stat
/////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

#define HELP_MSG "example:\
./a.out /usr/bin.sh\n\
"

void Usage()
{
	printf( HELP_MSG );
}

void PrintOutStat( struct stat *p_stat )
{
	if( S_ISBLK( p_stat->st_mode ) )
	{
		printf( "Block special file.\n" );
	}
	if( S_ISCHR( p_stat->st_mode ) )
	{
		printf( "character special file.\n" );
	}
	if( S_ISDIR( p_stat->st_mode ) )
	{
		printf( "directory.\n" );
	}
	if( S_ISFIFO( p_stat->st_mode ) )
	{
		printf( "Pipe or FIFO special file.\n" );
	}
	if( S_ISLNK( p_stat->st_mode ) )
	{
		printf( "symbolic link.\n" );
	}
	if( S_ISREG( p_stat->st_mode ) )
	{
		printf( "regular file.\n" );
	}
	if( S_ISSOCK( p_stat->st_mode ) )
	{
		printf( "socket.\n" );
	}
	if( S_ISWHT( p_stat->st_mode ) )
	{
		printf( "whiteout.\n" );
	}

	return;
}

int AnalyseFileStat( const char *file_path )
{
	struct stat stat_buf;
	int ret = -1;

	if( strlen( file_path ) <= 0 )
	{
		printf( "please tell me where the file is.\n" );
		return -1;
	}

	/*
	*******************************************************************************
	** Read, write or execute permission of the named file is not
	** required, but all directories listed in the path name leading to the file
	** must be searchable.
	*******************************************************************************
	*/

	// Need to protect the stat?
	
	// first,stat;then lstat
	ret = stat( file_path, &stat_buf );
	if( ret == -1 )
	{
		strerror( errno );
		return -1;
	}
	PrintOutStat( &stat_buf );

	// 
	ret = lstat( file_path, &stat_buf );
	if( ret == -1 )
	{
		strerror( errno );
		return -1;
	}
	PrintOutStat( &stat_buf );

	return 0;
}

int main( int argc, char **argv )
{
	// no file arg
	if( argc < 2 )
	{
		Usage();
		return -1;
	}

	// file exists?
	if( AnalyseFileStat( argv[1] ) == -1 )
	{
		perror( argv[0] );
		return -1;
	}

	return 0;
}
